using System;

public class Async : System.Runtime.CompilerServices.INotifyCompletion
{
	public Action Resume { get; private set; }
	int result;

	public Async()
	{
		Console.WriteLine("2 Async()");
	}

	public Async GetAwaiter() // 每次await都会获取一次
	{
		Console.WriteLine("3 GetAwaiter()");
		return this;
	}

	public bool IsCompleted // 每次await都会判断一次
	{
		get
		{
			Console.WriteLine("4 IsCompleted");
			return result != 0;
		}
	}

	public void OnCompleted(Action c) // 调用IsCompleted=false时设置一次
	{
		Console.WriteLine("5 OnCompleted()");
		Resume = c;
	}

	public int GetResult() // 调用IsCompleted=true时或OnCompleted的Action回调时获取一次
	{
		Console.WriteLine("7 GetResult()");
		return result;
	}

	static async void g(Async a)
	{
		int r = await a;
		Console.WriteLine("8, " + r);
		a.result = 0;
		r = await a;
		Console.WriteLine("9, " + r);
	}

	static void Main()
	{
		Console.WriteLine(System.Threading.SynchronizationContext.Current == null);
		Console.WriteLine("1 Main()");
		var a = new Async();
		g(a);
		Console.WriteLine("6 Main()");
		a.result = 1;
		a.Resume();
		Console.WriteLine("10 Main()");
		a.result = 0; // 即使IsCompleted会返回false,回调Action也直接调用GetResult获取结果
		a.Resume();
		Console.WriteLine("11 Main()");
	}
}
/*
True
1 Main()
2 Async()
3 GetAwaiter()
4 IsCompleted
5 OnCompleted()
6 Main()
7 GetResult()
8, 1
3 GetAwaiter()
4 IsCompleted
5 OnCompleted()
10 Main()
7 GetResult()
9, 0
11 Main()
*/
